#include "Game.h"

#include "SGD Wrappers/CSGD_Direct3D.h"
#include "SGD Wrappers/CSGD_DirectInput.h"
#include "SGD Wrappers/CSGD_TextureManager.h"
#include "SGD Wrappers/CSGD_XAudio2.h"

#include "States/IGameState.h"
#include "States/MenuSystem/MainMenuState.h"


CGame* CGame::s_Instance = nullptr;

CGame* CGame::GetInstance( void )
{
	if( s_Instance == nullptr )
		s_Instance = new CGame;

	return s_Instance;
}

void CGame::DeleteInstance( void )
{
	delete s_Instance;
	s_Instance = nullptr;
}

CGame::CGame( void )
{
	m_nScreenWidth	= 0;
	m_nScreenHeight = 0;
	m_bWindowed		= true;

	m_pCurrState	= nullptr;
}

CGame::~CGame( void )
{

}

void CGame::Initialize( HWND hWnd, HINSTANCE hInstance, int nScreenWidth, int nScreenHeight, bool bWindowed )
{
	m_nScreenHeight = nScreenHeight;
	m_nScreenWidth	= nScreenWidth;
	m_bWindowed		= bWindowed;

	CSGD_Direct3D::GetInstance()->InitDirect3D( hWnd, m_nScreenWidth, m_nScreenHeight, m_bWindowed );
	CSGD_DirectInput::GetInstance()->InitDirectInput( hWnd, hInstance, DI_KEYBOARD | DI_MOUSE );
	CSGD_TextureManager::GetInstance()->InitTextureManager( CSGD_Direct3D::GetInstance()->GetDirect3DDevice(), CSGD_Direct3D::GetInstance()->GetSprite() );
	CSGD_XAudio2::GetInstance()->InitXAudio2();

	ChangeState( CMainMenuState::GetInstance() );

}

bool CGame::Main( void )
{
	if( Input() == false )
		return false;

	Update();
	Render();

	return true;
}

void CGame::Shutdown( void )
{
	ChangeState( nullptr );

	CSGD_XAudio2::GetInstance()->ShutdownXAudio2();
	CSGD_TextureManager::GetInstance()->ShutdownTextureManager();
	CSGD_DirectInput::GetInstance()->ShutdownDirectInput();
	CSGD_Direct3D::GetInstance()->ShutdownDirect3D();
}

bool CGame::Input( void )
{
	CSGD_DirectInput::GetInstance()->ReadDevices();

	return m_pCurrState->Input();
}

void CGame::Update( void )
{
	CSGD_XAudio2::GetInstance()->Update();

	unsigned long ulTheTime = GetTickCount();

	float fElapsedTime = ( ulTheTime - m_ulCurrTime ) / 1000.0f;

	m_ulCurrTime = ulTheTime;

	if( fElapsedTime >= 0.125f )
		fElapsedTime = 0.125f;

	m_pCurrState->Update( fElapsedTime );
}

void CGame::Render( void )
{
	CSGD_Direct3D::GetInstance()->Clear( 0, 0, 0 );

	CSGD_Direct3D::GetInstance()->DeviceBegin();
	CSGD_Direct3D::GetInstance()->SpriteBegin();
	{
		m_pCurrState->Render();
	}
	CSGD_Direct3D::GetInstance()->SpriteEnd();
	CSGD_Direct3D::GetInstance()->DeviceEnd();

	CSGD_Direct3D::GetInstance()->Present();
}

void CGame::ChangeState( IGameState* pNewState )
{
	if( m_pCurrState != nullptr )
		m_pCurrState->Exit();

	m_pCurrState = pNewState;

	if( m_pCurrState != nullptr )
		m_pCurrState->Enter();
}